#include <sys/epoll.h>
#include "Log.hxx"
#include <cstring>
namespace EpollModule
{
    const int epoll_creat_size = 128;

    //该对象默认初始没有构建epoll对象的文件描述符是-1
    //构造函数调用后会自动构建epoll对象，也可以手动调用Init()方法
    //析构函数调用后会自动关闭epoll对象，也可以手动调用CloseEpoll()方法
    //反复对同一个对象调用Init，会关闭之前的epoll并重建新的epoll
    //反复对同一个对象调用CloseEpoll，会关闭之前的epoll，并且再次创建一个新的
    class Epoller
    {
    public:
        // 构造函数
        Epoller()
        {
            Init();
        }
        void Init()
        {
            if(m_epoll_fd>=0)
            {
                CloseEpoll();
            }
            m_epoll_fd = epoll_create(epoll_creat_size);
            if(m_epoll_fd < 0)
            {
                myService::lg(myService::Log::Fatal, "epoll_create1 failed ,errno = %d ,errmsg = %s,File %s,Line %d", errno, strerror(errno), __FILE__, __LINE__);
                exit(2); 
            }
            myService::lg(myService::Log::Info, "epoll_create1 success,epoll fd:%d", m_epoll_fd);
        }
        // 析构函数
        void CloseEpoll()
        {
            if(m_epoll_fd > 0)
            {
                close(m_epoll_fd);
                m_epoll_fd = -1;
            }
        }
        int AddFd(int fd,uint32_t event)
        {
            struct epoll_event ev;
            memset(&ev, 0, sizeof(ev));
            ev.events = event;
            ev.data.fd = fd;
            int ret = epoll_ctl(m_epoll_fd, EPOLL_CTL_ADD, fd, &ev);
            if(ret < 0)
            {
                myService:: lg(myService::Log::Error, "epoll_ctl add fd failed ,errno = %d ,errmsg = %s,File %s,Line %d", errno, strerror(errno), __FILE__, __LINE__);
            }
            return ret;
        }
        int DelFd(int fd)
        {
            struct epoll_event ev;
            memset(&ev, 0, sizeof(ev));
            int ret = epoll_ctl(m_epoll_fd, EPOLL_CTL_DEL, fd, &ev);
            if(ret < 0)
            { 
                myService:: lg(myService::Log::Error, "epoll_ctl del fd failed ,errno = %d ,errmsg = %s,File %s,Line %d", errno, strerror(errno), __FILE__, __LINE__);
            }
            return ret;
        }
        int ModFd(int fd,uint32_t event)
        {
            struct epoll_event ev;
            memset(&ev, 0, sizeof(ev));
            ev.events = event;
            ev.data.fd = fd;
            int ret = epoll_ctl(m_epoll_fd, EPOLL_CTL_MOD, fd, &ev);
            if(ret < 0)
            {
                myService:: lg(myService::Log::Error, "epoll_ctl mod fd failed ,errno = %d ,errmsg = %s,File %s,Line %d", errno, strerror(errno), __FILE__, __LINE__);
            }
            return ret;
        }
        //返回值是由有几个事件就绪
        int Wait(struct epoll_event* events,int max_events,int timeout  = -1)       
        {
            return epoll_wait(m_epoll_fd,events,max_events,timeout);
        }
        ~Epoller()
        {
            CloseEpoll();
        }

    private:
        int m_epoll_fd = -1;
    };
};
